﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenTK;
using OpenTK.Graphics.OpenGL4;
using OpenTK.Input;
using System.Drawing;
using OpenTK.Graphics;
using Common;

namespace T06.KeyboardAndMouse {
    class MyGameWindow : GameWindow {
        public MyGameWindow() {
            this.Load += MyGameWindow_Load;
            this.Resize += MyGameWindow_Resize;
            this.RenderFrame += MyGameWindow_RenderFrame;
            this.Unload += MyGameWindow_Unload;
            this.Width = 1280;
            this.Height = 720;

        }


        private void MyGameWindow_RenderFrame(object sender, FrameEventArgs e) {
            GL.ClearColor(.1f, .1f, .99f, .9f);
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

            Render();

            SwapBuffers();
            ProcessEvents();
        }

        float[] vertexBufferData = {
        -1.0f,-1.0f,-1.0f,
        -1.0f,-1.0f, 1.0f,
        -1.0f, 1.0f, 1.0f,
         1.0f, 1.0f,-1.0f,
        -1.0f,-1.0f,-1.0f,
        -1.0f, 1.0f,-1.0f,
         1.0f,-1.0f, 1.0f,
        -1.0f,-1.0f,-1.0f,
         1.0f,-1.0f,-1.0f,
         1.0f, 1.0f,-1.0f,
         1.0f,-1.0f,-1.0f,
        -1.0f,-1.0f,-1.0f,
        -1.0f,-1.0f,-1.0f,
        -1.0f, 1.0f, 1.0f,
        -1.0f, 1.0f,-1.0f,
         1.0f,-1.0f, 1.0f,
        -1.0f,-1.0f, 1.0f,
        -1.0f,-1.0f,-1.0f,
        -1.0f, 1.0f, 1.0f,
        -1.0f,-1.0f, 1.0f,
         1.0f,-1.0f, 1.0f,
         1.0f, 1.0f, 1.0f,
         1.0f,-1.0f,-1.0f,
         1.0f, 1.0f,-1.0f,
         1.0f,-1.0f,-1.0f,
         1.0f, 1.0f, 1.0f,
         1.0f,-1.0f, 1.0f,
         1.0f, 1.0f, 1.0f,
         1.0f, 1.0f,-1.0f,
        -1.0f, 1.0f,-1.0f,
         1.0f, 1.0f, 1.0f,
        -1.0f, 1.0f,-1.0f,
        -1.0f, 1.0f, 1.0f,
         1.0f, 1.0f, 1.0f,
        -1.0f, 1.0f, 1.0f,
         1.0f,-1.0f, 1.0f
    };
        float[] uvBufferData = {
        0.000059f, 0.000004f,
        0.000103f, 0.336048f,
        0.335973f, 0.335903f,
        1.000023f, 0.000013f,
        0.667979f, 0.335851f,
        0.999958f, 0.336064f,
        0.667979f, 0.335851f,
        0.336024f, 0.671877f,
        0.667969f, 0.671889f,
        1.000023f, 0.000013f,
        0.668104f, 0.000013f,
        0.667979f, 0.335851f,
        0.000059f, 0.000004f,
        0.335973f, 0.335903f,
        0.336098f, 0.000071f,
        0.667979f, 0.335851f,
        0.335973f, 0.335903f,
        0.336024f, 0.671877f,
        1.000004f, 0.671847f,
        0.999958f, 0.336064f,
        0.667979f, 0.335851f,
        0.668104f, 0.000013f,
        0.335973f, 0.335903f,
        0.667979f, 0.335851f,
        0.335973f, 0.335903f,
        0.668104f, 0.000013f,
        0.336098f, 0.000071f,
        0.000103f, 0.336048f,
        0.000004f, 0.671870f,
        0.336024f, 0.671877f,
        0.000103f, 0.336048f,
        0.336024f, 0.671877f,
        0.335973f, 0.335903f,
        0.667969f, 0.671889f,
        1.000004f, 0.671847f,
        0.667979f, 0.335851f
    };

        Shader shader;
        Vao vao;
        int textureId;
        Vbo vertexBuffer, uvBuffer;
        VertexAttribManager soa;
        private void MyGameWindow_Load(object sender, EventArgs e) {

            VSync = VSyncMode.Off;
            GL.Enable(EnableCap.DepthTest);


            InputControls.setCursorPosition(this,new Point(this.Width/2,this.Height/2));
            GL.Enable(EnableCap.DepthTest);
            GL.DepthFunc(DepthFunction.Less);
            GL.Enable(EnableCap.CullFace);
            vao = new Vao();
            shader = new Shader("shader.vs", "shader.fs");
            vertexBuffer = new Vbo(BufferTarget.ArrayBuffer, BufferUsageHint.StaticDraw, vertexBufferData);
            uvBuffer = new Vbo(BufferTarget.ArrayBuffer, BufferUsageHint.StaticDraw, uvBufferData);

            textureId = DdsReader.LoadDds("uvTemplate.dds");

            soa = new VertexAttribManager();
            soa.AddAttrib(3, vertexBuffer, VertexAttribPointerType.Float, false);
            soa.AddAttrib(2, uvBuffer, VertexAttribPointerType.Float, false);

        }

        private void Render() {
            shader.Use();
            InputControls.computeMatricesFromInput(this);
            Matrix4 projection = InputControls.ProjectionMatrix;
            Matrix4 view = InputControls.ViewMatrix;
            Matrix4 model = Matrix4.Identity;
            Matrix4 mvp = model * view * projection;

            shader.SetMatrix4("MVP",ref mvp);
            GL.ActiveTexture(TextureUnit.Texture0);
            GL.BindTexture(TextureTarget.Texture2D, textureId);
            shader.SetInt("myTextureSampler", 0);

            soa.Enable();
            GL.DrawArrays(PrimitiveType.Triangles, 0, 12 * 3);
            soa.Disable();

        }

        private void MyGameWindow_Resize(object sender, EventArgs e) {
            GL.Viewport(0, 0, Width, Height);
        }



        private void MyGameWindow_Unload(object sender, EventArgs e) {
            shader.Dispose();
            vertexBuffer.Dispose();
            uvBuffer.Dispose();
            vao.Dispose();
            GL.DeleteTexture(textureId);
        }

    }
}
